import { useEffect } from "@/framework/vue/hooks";
import hotkeys, { type KeyHandler } from "hotkeys-js";

type HotkeysOptions = {
  scope?: string;
  element?: HTMLElement | null;
  keyup?: boolean | null;
  keydown?: boolean | null;
  capture?: boolean;
  splitKey?: string;
  single?: boolean;
};

export function useHotkey(key: HotkeyDeclare, method: KeyHandler): void;
export function useHotkey(key: string, method: KeyHandler): void;
export function useHotkey(key: string, options: HotkeysOptions, method: KeyHandler): void;

export function useHotkey(key: string | HotkeyDeclare, options: HotkeysOptions | KeyHandler, method?: KeyHandler) {
  useEffect(() => {
    const k = typeof key === "string" ? key : key.key;

    const opts: HotkeysOptions = typeof options === "object" ? options : {};
    if (typeof key === "object" && key.opts) {
      Object.assign(opts, key.opts);
    }

    const fn: KeyHandler = typeof options === "object" ? method! : options;

    hotkeys(k, opts, fn);

    return () => {
      if (opts.scope) hotkeys.deleteScope(opts.scope);
      hotkeys.unbind(k, fn);
    };
  });
}

export interface HotkeyDeclare {
  key: string;
  desc?: string;
  opts?: HotkeysOptions;
}

export function useHotkeys(keys: [HotkeyDeclare, KeyHandler][], options?: HotkeysOptions) {
  useEffect(() => {
    for (const [key, method] of keys) {
      const opts = { ...key.opts, ...options };
      hotkeys(key.key, opts || {}, method);
    }

    return () => {
      if (options?.scope) hotkeys.deleteScope(options.scope);
      for (const [key, method] of keys) {
        hotkeys.unbind(key.key, method);
      }
    };
  });
}
